package com.lagou.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

@RestController
@RequestMapping("/autodeliver")
public class AutodeliverController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    /*@GetMapping("/checkState/{userId}")
    public Integer findResumeOpenState(@PathVariable Long userId) {
        //第一步，从eureka客户端获取对于服务提供者的实例列表
        List<ServiceInstance> instances = discoveryClient.getInstances("lagou-sc-service-resume");
        //通过负载均衡获取调用的服务
        ServiceInstance serviceInstance = instances.get(0);
        System.out.println("元数据：" + serviceInstance);
        //从元数据中获取对于的端口和ip
        String host = serviceInstance.getHost();
        int port = serviceInstance.getPort();
        //拼接好url
        String url = "http://" + host + ":" + port + "/resume/openstate/" + userId;
        System.out.println("拼接好的url：" + url);
        //发起调用
        Integer forObject = restTemplate.getForObject(url, Integer.class);
        return forObject;
    }*/


    /**
     * 使用ribbon的负载均衡
     *
     * @param userId
     * @return
     */
    @GetMapping("/checkState/{userId}")
    public Integer findResumeOpenState(@PathVariable Long userId) {
        //不再需要自己获取列表自己挑选服务进行调用
        //将host和port改为对于服务名即可
        String url = "http://lagou-sc-service-resume/resume/openstate/" + userId;
        System.out.println("拼接好的url：" + url);
        //发起调用
        Integer forObject = restTemplate.getForObject(url, Integer.class);
        return forObject;
    }

    /**
     * hystrix 熔断
     *
     * @param userId
     * @return
     */
    @GetMapping("/checkStateTimeOut/{userId}")
    @HystrixCommand(
            //线程池唯一标识
            threadPoolKey = "checkStateFallback",
            //线程池的一些细节配置
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize", value = "2"),
                    @HystrixProperty(name = "maxQueueSize", value = "20")//等待队列线程数
            },
            //一些细节配置
            commandProperties = {
                    //key-value
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
            }
    )//添加熔断控制
    public Integer findResumeOpenStateTimeOut(@PathVariable Long userId) {
        //不再需要自己获取列表自己挑选服务进行调用
        //将host和port改为对于服务名即可
        String url = "http://lagou-sc-service-resume/resume/openstate/" + userId;
        System.out.println("拼接好的url：" + url);
        //发起调用
        Integer forObject = restTemplate.getForObject(url, Integer.class);
        return forObject;
    }

    /**
     * hystrix 服务降级
     *
     * @param userId
     * @return
     */
    @GetMapping("/checkStateFallback/{userId}")
    @HystrixCommand(
            //线程池唯一标识
            threadPoolKey = "checkStateFallback",
            //线程池的一些细节配置
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize", value = "2"),
                    @HystrixProperty(name = "maxQueueSize", value = "20")//等待队列线程数
            },
            //一些细节配置
            commandProperties = {
                    //key-value
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")

                    //hystrix高级配置，定制工作流程
                    ,
                    // 统计时间窗口定义
                    @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "8000"),
                    // 统计时间窗口内的最小请求数
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2"),
                    // 统计时间窗口内的错误数量百分比阈值
                    @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
                    // 自我修复时的活动窗口⻓度
                    @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "3000")
            },
            fallbackMethod = "fallback"
    )//添加熔断控制
    public Integer findResumeOpenStateFallback(@PathVariable Long userId) {
        //不再需要自己获取列表自己挑选服务进行调用
        //将host和port改为对于服务名即可
        String url = "http://lagou-sc-service-resume/resume/openstate/" + userId;
        System.out.println("拼接好的url：" + url);
        //发起调用
        Integer forObject = restTemplate.getForObject(url, Integer.class);
        return forObject;
    }

    //服务降级方法
    public Integer fallback(Long userId) {
        return -1;
    }
}
